﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Kugar.Core.ExtMethod
{
    public static class DataContractJsonSerializerExt
    {
        private static Dictionary<Type, DataContractJsonSerializer> dscCache = new Dictionary<Type, DataContractJsonSerializer>(5);

        public static T ReadObject<T>(this DataContractJsonSerializer serializer, string json)
        {
            return ReadObject(serializer, json, null, default(T));
        }

        public static T ReadObject<T>(this DataContractJsonSerializer serializer, string json, Encoding encoding, T defaultValue)
        {
            if (string.IsNullOrEmpty(json))
            {
                return defaultValue;
            }

            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            using (var ms = new MemoryStream(encoding.GetBytes(json)))
            {
                try
                {
                    var tempObj = (T)serializer.ReadObject(ms);

                    return tempObj;
                }
                catch (Exception)
                {
                    return defaultValue;
                }
            }


        }

        public static string WriteObject(this DataContractJsonSerializer serializer, object srcObj)
        {
            return WriteObject(serializer, srcObj, null);
        }

        public static string WriteObject(this DataContractJsonSerializer serializer, object srcObj, Encoding encoding)
        {
            if (srcObj == null)
            {
                return string.Empty;
            }

            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            using (var ms = new MemoryStream())
            {
                try
                {
                    serializer.WriteObject(ms, srcObj);

                    var buf = ms.ToArray();

                    return encoding.GetString(buf, 0, buf.Length);
                }
                catch (Exception)
                {
                    return string.Empty;
                }
            }

        }

        public static T ReadObject<T>(this string json, Encoding encoding, T defauleValue)
        {
            if (string.IsNullOrEmpty(json))
            {
                return defauleValue;
            }

            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            DataContractJsonSerializer se = null;

            Type type = typeof(T);

            if (dscCache.ContainsKey(type))
            {
                se = dscCache[type];
            }
            else
            {
                se = new DataContractJsonSerializer(type);
                dscCache.Add(type, se);
            }

            return se.ReadObject<T>(json, encoding, defauleValue);

        }

        public static T ReadObject<T>(this string json,T defaultValue)
        {
            return ReadObject<T>(json, null, defaultValue);
        }

        public static T ReadObject<T>(this string json)
        {
            return ReadObject<T>(json, null, default(T));
        }

        public static string WriteObject(this object srcObj)
        {
            return WriteObject(srcObj, null);
        }

        public static string WriteObject(this object srcObj, Encoding encoding)
        {
            if (srcObj == null)
            {
                return string.Empty;
            }

            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }

            DataContractJsonSerializer se = null;

            var type = srcObj.GetType();

            if (dscCache.ContainsKey(type))
            {
                se = dscCache[type];
            }
            else
            {
                se = new DataContractJsonSerializer(type);
                dscCache.Add(type, se);
            }

            return se.WriteObject(srcObj, encoding);
        }
    }
}
